<?php
/**
 * Library Of Shared Code (LOSC)
 *
 * LICENSE
 *
 * This source file is subject to the New BSD License that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category   LOSC Framework
 * @package    Exception
 * @copyright  Copyright (c) 2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://creativecommons.org/licenses/BSD/  New BSD License
 */

/**
 * This exception class add i18n support to exceptions
 *
 * @category   LOSC Framework
 * @package    Exception
 * @copyright  Copyright (c) 2008 Robin Skoglund (http://robinsk.net/)
 * @license    http://creativecommons.org/licenses/BSD/  New BSD License
 */
class Losc_Exception extends Exception
{
    /**
     * Translator to use when translating messages
     *
     * @var Zend_Translate_Adapter
     */
    protected static $_translator;
    
    /**
     * Whether exception messages should be translated
     *
     * @var boolean
     */
    protected static $_useTranslator = true;
    
    /**
     * Localized exception message
     *
     * @var string
     */
    protected $_localizedMessage;
    
    /**
     * Creates exception
     *
     * @param string|array $message  [optional] exception message. If an array
     *                               is given, the first element is used as the
     *                               message, and the rest for substitutions in
     *                               the message, using vsprintf().
     * @param int          $code     [optional] exception code
     */
    public function __construct($message = null, $code = 0)
    {
        if ($message) {
            if (is_array($message)) {
                $extractedMessage = array_shift($message);
                $values = $message;
                $message = $extractedMessage;
            } else {
                $values = array();
            }
            
            if (self::getUseTranslator() && $t = self::getTranslator()) {
                // translate if translator is available
                $localized = $t->translate($message);
            } else {
                $localized = $message;
            }
                
            if (count($values)) {
                // do value substitution if any
                $message = vsprintf($message, $values);
                $localized = vsprintf($localized, $values);
            }
            
            $this->_localizedMessage = $localized;
        }
        
        parent::__construct($message, $code);
    }
    
    /**
     * Returns localized exception message
     *
     * @return string
     */
    public function getLocalizedMessage()
    {
        if ($this->_localizedMessage !== null) {
            return $this->_localizedMessage;
        }
        
        return $this->getMessage();
    }
    
    /**
     * Sets translator to use when translating exception messages
     *
     * @param  Zend_Translate|Zend_Translate_Adapter $translator  translator
     * @return void
     */
    public static function setTranslator($translator)
    {
        if ($translator instanceof Zend_Translate) {
            self::$_translator = $translator->getAdapter();
        } elseif ($translator instanceof Zend_Translate_Adapter) {
            self::$_translator = $translator;
        }
    }
    
    /**
     * Returns translator to use when translating exception messages
     *
     * @return Zend_Translate_Adapter|null
     */
    public static function getTranslator()
    {
        $key = 'Zend_Translate';
        if (null == self::$_translator && Zend_Registry::isRegistered($key)) {
            self::setTranslator(Zend_Registry::get($key));
        }
        
        return self::$_translator;
    }
    
    /**
     * Sets whether or not exception messages should be translated
     *
     * @param  boolean $flag  use translator or not
     * @return void
     */
    public static function setUseTranslator($flag)
    {
        self::$_useTranslator = (boolean) $flag;
    }
    
    
    /**
     * Returns whether or not exception messages should be translated
     *
     * @return boolean
     */
    public static function getUseTranslator()
    {
        return self::$_useTranslator;
    }
}
